home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / PowerD / powerd / source / dmod.d < prev    next >
Encoding:
Text File  |  2002-10-28  |  12.5 KB  |  604 lines

  1. // view powerd binary module (#?.b) generated by powerd v0.12 and later
  2.  
  3. // 1.0 initial release
  4. // 1.1 (27.1.2001)
  5. //   added unions (in binary modules introduced with PowerD 0.17)
  6. // 1.2 (29.12.2001)
  7. //   added support for structs and cunions
  8. //   improved object layout
  9. // 1.3 (18.1.2002)
  10. //   added support for multidimensional items in objects (introduced in dc 0.19alpha5)
  11. //   added TDEF support
  12. //   added OFFSET/RELOFS/ALIGN keywords support in OBJECTs
  13.  
  14. BYTE 0,0,'$VER:dmod v1.3 by MarK (18.1.2002)',0,0
  15.  
  16. PROC DisplayMODULE(mem:PTR TO CHAR)
  17.     DEF    ver,rev,count,nl,ml,namelist:PTR TO CHAR,type,flags,acount,rcount,l,offset,
  18.             base:PTR TO CHAR
  19.  
  20.     IF Long(mem)<>"DMOD"
  21.         PrintF('\s: unknown filetype','dmod')
  22.         RETURN
  23.     ENDIF
  24.     mem+=4                        // skip "DMOD"
  25.     ver:=Word(mem)
  26.     rev:=Word(mem+2)
  27.     mem+=4                        // skip ver,rev
  28.     PrintF('// requied version of powerd: v\d.\z\d[2]\n\n',ver,rev)
  29.  
  30.     IF Long(mem)="MODS"
  31.         PrintF('MODULE\t')
  32.         count:=Word(mem+4)
  33.         mem+=6
  34.         WHILE count
  35.             count--
  36.             nl:=Word(mem)
  37.             mem+=2
  38.             PrintF('''\s''',mem)
  39.             mem+=nl+1
  40.             IF Odd(mem) THEN mem++
  41.             IF CtrlC() THEN RETURN
  42.         EXITIF count=0 DO PrintF('\n\n')
  43.             PrintF(',\n\t\t\t')
  44.         ENDWHILE
  45.     ENDIF
  46.  
  47.     IF Long(mem)="CNST"                // constant list
  48.         PrintF('CONST\t')
  49.         count:=Word(mem+4)            // count of constants
  50.         ml:=Long(mem+6)
  51.         nl:=Long(mem+10)
  52.         mem+=14
  53.         namelist:=mem+ml
  54.         WHILE count
  55.             count--
  56.             PrintF('\s=',namelist)
  57.             type:=UByte(mem++)
  58.             flags:=UByte(mem++)
  59.             IF type=$ff
  60.                 PrintF('0')
  61.             ELSEIF type=8                // DT_DOUBLE
  62.                 PrintF('$\z\h[8].\z\h[8]',Long(mem),Long(mem+4))
  63.                 mem+=8
  64.             ELSEIF flags&%10            // S_TAG
  65.                 PrintF('$\h',Word(mem)|$80000000)
  66.                 mem+++
  67.             ELSEIF type=3                // DT_WORD
  68.                 PrintF('\d',Word(mem))
  69.                 mem+++
  70.             ELSE
  71.                 acount:=Long(mem)
  72.                 PrintF(IF acount>=-32768 AND acount<=32767 THEN '\d' ELSE '$\h',acount)
  73. //                PrintF(IF Long(mem)>=-32768 AND Long(mem)<=32767 THEN '\d' ELSE '$\h',Long(mem))
  74.                 mem+=4
  75.             ENDIF
  76.             namelist+=StrLen(namelist)+1
  77.             IF namelist[0]="\0" THEN namelist++
  78.             IF CtrlC() THEN RETURN
  79.         EXITIF count=0 DO PrintF('\n\n')
  80.             PrintF(',\n\t\t')
  81.         ENDWHILE
  82.         IF Odd(namelist) THEN namelist++
  83.         mem:=namelist
  84.     ENDIF
  85.  
  86.     IF Long(mem)="OBJC"            -> object list
  87.         ml:=Long(mem+4)
  88.         nl:=Long(mem+8)
  89.         acount:=Word(mem+12)
  90.         count:=Word(mem+14)
  91.         mem+=16
  92.         namelist:=mem+ml
  93.         offset:=0
  94.  
  95.         WHILE acount
  96.             mem,namelist:=LoadOBJECT(mem,namelist,offset)
  97.             acount--
  98.             IF CtrlC() THEN RETURN
  99.         ENDWHILE
  100.  
  101.         IF Odd(namelist) THEN namelist++
  102.         mem:=namelist
  103.     ENDIF
  104.  
  105.     IF Long(mem)="#def"            -> #define list
  106.         count:=Word(mem+4)
  107.         acount:=Word(mem+6)
  108.         ml:=Long(mem+8)
  109.         nl:=Long(mem+12)
  110.         mem+=16
  111.         namelist:=mem+ml
  112.  
  113.         WHILE count
  114.             count--
  115.             PrintF('#define \s',namelist)
  116.             namelist+=mem[1]+1
  117.             l:=Word(mem+2)
  118.             acount:=mem[0]
  119.             mem+=4
  120.             IF acount
  121.                 PrintF('(')
  122.                 WHILE acount
  123.                     PrintF('\s',namelist)
  124.                     namelist+=mem[1]+1
  125.                     mem+++
  126.                     acount--
  127.                     IF CtrlC() THEN RETURN
  128.                 EXITIF acount=0 DO PrintF(') ')
  129.                     PrintF(',')
  130.                 ENDWHILE
  131.             ELSE PrintF(' ')
  132.             PrintF('\s\n',namelist)
  133.             namelist+=l+1
  134.             IF CtrlC() THEN RETURN
  135.         ENDWHILE
  136.  
  137.         IF Odd(namelist) THEN namelist++
  138.         mem:=mem+nl
  139.     ENDIF
  140.  
  141.     IF Long(mem)="LIBR"            // function list
  142.         count:=Word(mem+4)        // count of functions
  143.         nl:=Word(mem+6)            // base name length
  144.         ml:=Long(mem+12)            // block length
  145.         mem+=16
  146.         base:=mem
  147.         mem+=nl
  148.         IF mem[0]="\0" THEN mem++
  149.         namelist:=mem+ml
  150.         PrintF('LIBRARY \s\n\t',base)
  151.  
  152.         WHILE count
  153.             count--
  154.             offset:=Word(mem)
  155.             acount:=mem[2]
  156.             rcount:=mem[3]&$1f
  157.             ver:=mem[3]>>5            // get ppc function type
  158.             SELECT ver
  159.             CASE 0;    PrintF('M68K,')
  160.             CASE 1;    PrintF('PPC,')
  161.             CASE 2;    PrintF('PPC2,')
  162.             CASE 3;    PrintF('PPC0,')
  163.             ENDSELECT
  164.             mem+=4
  165.             PrintF('\s(',namelist)
  166.             namelist+=StrLen(namelist)+1
  167.             WHILE acount
  168.                 acount--
  169.                 IF ver
  170.                     SELECT mem[2]
  171.                     CASE 0 TO 31;    PrintF('r\d',mem[2]&%11111)
  172.                     CASE 32 TO 63;    PrintF('f\d',mem[2]&%11111)
  173.                     ENDSELECT
  174.                 ELSE
  175.                     SELECT mem[2]
  176.                     CASE 0 TO 7;    PrintF('d\d',mem[2]&%111)
  177.                     CASE 8 TO 15;    PrintF('a\d',mem[2]&%111)
  178.                     CASE 16 TO 23;    PrintF('fp\d',mem[2]&%111)
  179.                     ENDSELECT
  180.                 ENDIF
  181.                 type:=mem[0]
  182.                 flags:=mem[1]        // means default value set
  183.                 nl:=mem[3]
  184.                 mem+=4
  185.                 IF flags
  186.                     IF type=8
  187.                         PrintF('=$\z\h[8].\z\h[8]',Long(mem),Long(mem+4))
  188.                         mem+=8
  189.                     ELSE
  190.                         PrintF('=$\d',Long(mem))
  191.                         mem+=4
  192.                     ENDIF
  193.                 ENDIF
  194.                 IF type
  195.                     PrintF(':\s',TypeStr(type))
  196.                 ENDIF
  197.                 IF nl
  198.                     PrintF('\s',namelist)
  199.                     namelist+=nl+1
  200.                 ENDIF
  201.             EXITIF acount=0
  202.                 PrintF(',')
  203.                 IF CtrlC() THEN RETURN
  204.             ENDWHILE
  205.             PrintF(')')
  206.  
  207.             IF rcount
  208.                 PrintF('(')
  209.                 WHILE rcount
  210.                     rcount--
  211.                     IF ver
  212.                         SELECT mem[2]
  213.                         CASE 0 TO 31;    PrintF('r\d',mem[2]&%11111)
  214.                         CASE 32 TO 63;    PrintF('f\d',mem[2]&%11111)
  215.                         ENDSELECT
  216.                     ELSE
  217.                         SELECT mem[2]
  218.                         CASE 0 TO 7;    PrintF('d\d',mem[2]&%111)
  219.                         CASE 8 TO 15;    PrintF('a\d',mem[2]&%111)
  220.                         CASE 16 TO 23;    PrintF('fp\d',mem[2]&%111)
  221.                         ENDSELECT
  222.                     ENDIF
  223.                     type:=mem[0]
  224.                     nl:=mem[3]
  225.                     mem+=4
  226.                     IF type
  227.                         PrintF(':\s',TypeStr(type))
  228.                     ENDIF
  229.                     IF nl
  230.                         PrintF('\s',namelist)
  231.                         namelist+=nl+1
  232.                     ENDIF
  233.                 EXITIF rcount=0 DO PrintF(')')
  234.                     PrintF(',')
  235.                     IF CtrlC() THEN RETURN
  236.                 ENDWHILE
  237.             ENDIF
  238.             PrintF('=\d',offset)
  239.             IF CtrlC() THEN RETURN
  240.         EXITIF count=0 DO PrintF('\n\n')
  241.             PrintF(',\n\t')
  242.         ENDWHILE
  243.         IF Odd(namelist) THEN namelist++
  244.         mem:=namelist
  245.     ENDIF
  246.  
  247.     IF Long(mem)="EXPR"            // external function list
  248.         count:=Word(mem+4)
  249.         ml:=Long(mem+10)
  250.         nl:=Long(mem+14)
  251.         mem+=18
  252.         namelist:=mem+ml
  253.  
  254.         WHILE count
  255.             count--
  256.             SELECT type:=mem[0]
  257.             CASE 11;    PrintF('EPROC')
  258.             CASE 13;    PrintF('LPROC')
  259.             CASE 14;    PrintF('RPROC')
  260.             ENDSELECT
  261. /*
  262.             IF StrCmp(namelist,'Ror')
  263.                 xxxxxx:
  264.                 l:=l
  265.             ENDIF
  266. */
  267.             PrintF(' \s(',namelist)
  268.             namelist+=StrLen(namelist)+1
  269.             flags:=mem[1]
  270.             acount:=mem[2]
  271.             rcount:=mem[3]
  272.             mem+=4
  273.             offset:=0
  274.             IF flags&%01
  275.                 offset:=namelist
  276.                 namelist+=StrLen(namelist)+1
  277.             ENDIF
  278.  
  279.             IF type=14
  280.                 IF flags&%10
  281.                     l:=namelist
  282.                     namelist+=StrLen(namelist)+1
  283.                 ELSE
  284.                     l:=NIL
  285.                 ENDIF
  286.             ENDIF
  287.  
  288.             WHILE acount
  289.                 acount--
  290.                 type:=mem[0]
  291.                 flags:=mem[1]
  292.                 SELECT mem[3]
  293.                 CASE 0 TO 7;    PrintF('d\d',mem[3]&%111)
  294.                 CASE 8 TO 15;    PrintF('a\d',mem[3]&%111)
  295.                 CASE 16 TO 23;    PrintF('fp\d',mem[3]&%111)
  296.                 DEFAULT;            PrintF('\c',"z"-acount)        // stack
  297.                 ENDSELECT
  298.                 mem+=4
  299.                 IF flags&%01
  300.                     IF type=8    // DT_DOUBLE
  301.                         PrintF('=$\z\h[8].\z\h[8]',Long(mem),Long(mem+4))
  302.                         mem+=8
  303.                     ELSE
  304.                         PrintF('=\d',Long(mem))
  305.                         mem+=4
  306.                     ENDIF
  307.                 ENDIF
  308.                 IF type
  309.                     PrintF(':\s',TypeStr(type))
  310.                     IF flags&%10
  311.                         PrintF('\s',namelist)
  312.                         namelist+=StrLen(namelist)+1
  313.                     ENDIF
  314.                 ENDIF
  315.             EXITIF acount=0
  316.                 PrintF(',')
  317.                 IF CtrlC() THEN RETURN
  318.             ENDWHILE
  319.             PrintF(')')
  320.  
  321.             IF rcount
  322.                 PrintF('(')
  323.                 WHILE rcount
  324.                     rcount--
  325.                     type:=mem[0]
  326.                     SELECT mem[1]
  327.                     CASE 0 TO 7;    PrintF('d\d',mem[1]&%111)
  328.                     CASE 8 TO 15;    PrintF('a\d',mem[1]&%111)
  329.                     CASE 16 TO 23;    PrintF('fp\d',mem[1]&%111)
  330.                     ENDSELECT
  331.                     mem+++
  332.                     IF type THEN PrintF(':\s',TypeStr(type))
  333.                     IF type=10 OR type=42 OR type=74 OR type=138
  334.                         PrintF('\s',namelist)
  335.                         namelist+=StrLen(namelist)+1
  336.                     ENDIF
  337.                 EXITIF rcount=0 DO PrintF(')')
  338.                     PrintF(',')
  339.                     IF CtrlC() THEN RETURN
  340.                 ENDWHILE
  341.             ENDIF
  342.  
  343.             IF offset THEN PrintF(' OF \s',offset)
  344.             IF l THEN PrintF('=''\s''',l)
  345.             IF CtrlC() THEN RETURN
  346.             PrintF('\n')
  347.         ENDWHILE
  348.         PrintF('\n')
  349.         IF Odd(namelist) THEN namelist++
  350.         mem+=nl
  351.     ENDIF
  352.  
  353.     IF Long(mem)="EDEF"
  354.         PrintF('EDEF\t')
  355.         count:=Word(mem+4)
  356.         ml:=Long(mem+6)
  357.         nl:=Long(mem+10)
  358.         mem+=14
  359.         namelist:=mem+ml
  360.  
  361.         WHILE count
  362.             count--
  363.             PrintF('\s',namelist)
  364.             namelist+=StrLen(namelist)+1
  365.             IF mem[0] THEN PrintF(':\s',TypeStr(mem[0]))
  366.             IF mem[1]
  367.                 PrintF('\s',namelist)
  368.                 namelist+=StrLen(namelist)+1
  369.             ENDIF
  370.             mem+++
  371.         EXITIF count=0 DO PrintF('\n\n')
  372.             PrintF(',\n\t\t')
  373.             IF CtrlC() THEN RETURN
  374.         ENDWHILE
  375.         mem+=nl
  376.     ENDIF
  377.  
  378.     IF Long(mem)="LINK"
  379.         PrintF('OPT\t')
  380.         count:=Word(mem+4)
  381.         mem:=mem+6
  382.         WHILE count
  383.             count--
  384.             nl:=Word(mem)
  385.             mem+++
  386.             PrintF('''\s''',mem)
  387.             mem:=mem+nl
  388.             IF Odd(nl) THEN mem++
  389.         EXITIF count=0 DO PrintF('\n')
  390.             PrintF(',\n\t\t')
  391.             IF CtrlC() THEN RETURN
  392.         ENDWHILE
  393.     ENDIF
  394.  
  395.     IF Long(mem)="HEAD"
  396.         nl:=Word(mem+4)
  397.         mem+=6
  398.         PrintF('OPT\tHEAD=''\s''\n',mem)
  399.         mem+=nl
  400.         IF Odd(nl) THEN mem++
  401.     ENDIF
  402.  
  403.     IF Long(mem)="TDEF"
  404.         PrintF('TDEF\t')
  405.         count:=Word(mem+4)
  406.         ml:=Long(mem+6)
  407.         nl:=Long(mem+10)
  408.         mem:=mem+14
  409.         namelist:=mem+ml
  410.         WHILE count
  411.             PrintF('\s:\s',namelist,TypeStr(mem[0]))
  412.             namelist+=mem[1]+1
  413.             IF mem[2]
  414.                 PrintF(' \s',namelist)
  415.                 namelist+=mem[2]+1
  416.             ENDIF
  417.             mem+=4
  418.             count--
  419.             IF count THEN PrintF(',\n\t\t') ELSE PrintF('\n\n')
  420.             IF CtrlC() THEN RETURN
  421.         ENDWHILE
  422.         mem+=nl
  423.         IF Odd(mem) THEN mem++
  424.     ENDIF
  425.  
  426. ENDPROC
  427.  
  428. PROC LoadOBJECT(mem:PTR TO CHAR,nmem:PTR TO CHAR,offset,depth=0)(PTR TO CHAR,PTR TO CHAR)
  429.     DEF    count
  430.     IF mem[0]=0        // next object
  431.         do_depth
  432.         PrintF('OBJECT \s',nmem)
  433.         nmem+=mem[1]+1
  434.         IF mem[2]
  435.             PrintF(' OF \s\n',nmem)
  436.             nmem+=mem[2]+1
  437.         ELSE PrintF('\n')
  438.         mem+=8
  439.         WHILE mem[0]>=1 AND mem[0]<=5
  440.             mem,nmem:=LoadOBJECT(mem,nmem,offset,depth+1)
  441.         ELSEWHILE mem[0]>=6 AND mem[0]<=8
  442.             mem,nmem:=LoadOBJECT(mem,nmem,offset,depth)
  443.         ALWAYS
  444.         EXITIF mem[0]<1 AND mem[0]>8 DO PrintF('\n\n')
  445.             PrintF(',\n')
  446.             IF CtrlC() THEN RETURN
  447.         ENDWHILE
  448.     ELSEIF mem[0]=1    // normal item
  449.         do_depth
  450.         PrintF('\s',nmem)
  451.         nmem+=mem[1]+1
  452.         IF Word(mem+6) THEN PrintF('[\d]',Word(mem+6))
  453.         PrintF(':\s',TypeStr(mem[2]))
  454.         IF mem[5]
  455.             PrintF('\s',nmem)
  456.             nmem+=mem[5]+1
  457.         ENDIF
  458.         mem+=10
  459.     ELSEIF mem[0]=5    // normal multidimensional item
  460.         do_depth
  461.         PrintF('\s',nmem)
  462.         nmem+=mem[1]+1
  463.         IF Word(mem+6)
  464.             PrintF('[\d',Word(mem+6))
  465.             IF Word(mem+10)
  466.                 PrintF(',\d',Word(mem+10))
  467.                 IF Word(mem+12)
  468.                     PrintF(',\d]',Word(mem+12))
  469.                 ELSE PrintF(']')
  470.             ELSE PrintF(']')
  471.         ENDIF
  472.         PrintF(':\s',TypeStr(mem[2]))
  473.         IF mem[5]
  474.             PrintF('\s',nmem)
  475.             nmem+=mem[5]+1
  476.         ENDIF
  477.         mem+=14
  478.     ELSEIF mem[0]=2    // union/object
  479.         DEF    first=TRUE
  480.         WHILE mem[0]=2
  481.             do_depth
  482.             PrintF('\s \s\n',IF first THEN 'OBJECT' ELSE 'UNION',nmem)
  483.             nmem+=mem[1]+1
  484.             count:=mem[2]
  485.             mem+=6
  486.             WHILE count
  487.                 count--
  488.                 mem,nmem:=LoadOBJECT(mem,nmem,offset,depth+1)
  489.                 PrintF(IF (mem[0]=1 OR mem[0]=3) AND count>0 THEN ',\n' ELSE '\n')
  490.                 IF CtrlC() THEN RETURN
  491.             ENDWHILE
  492.             first:=FALSE
  493.         ENDWHILE
  494.         PrintF('\tENDOBJECT')
  495.     ELSEIF mem[0]=3    // struct
  496.         do_depth
  497.         DEF    name
  498.         count:=mem[2]
  499.         offset:=Word(mem+4)
  500.         name:=nmem
  501.         nmem+=mem[1]+1
  502.         mem+=6
  503.         PrintF('[\n')
  504.         WHILE count
  505.             count--
  506.             mem,nmem:=LoadOBJECT(mem,nmem,offset,depth+1)
  507.             PrintF(IF count>0 THEN ',\n' ELSE '\n')
  508.             IF CtrlC() THEN RETURN
  509.         ENDWHILE
  510.         do_depth
  511.         PrintF(']:\s',name)
  512.     ELSEIF mem[0]=4    // cunion
  513.         count:=mem[1]
  514.         mem+=4
  515.         do_depth
  516.         PrintF('CUNION\n')
  517.         WHILE count
  518.             count--
  519.             mem,nmem:=LoadOBJECT(mem,nmem,offset,depth+1)
  520.             PrintF(IF count>0 THEN ',\n' ELSE '\n')
  521.             IF CtrlC() THEN RETURN
  522.         ENDWHILE
  523.         PrintF('\tENDUNION')
  524.     ELSEIF mem[0]=6    // offset
  525.         do_depth
  526.         PrintF('OFFSET \d',Word(mem+2))
  527.         mem+=4
  528.     ELSEIF mem[0]=7    // relofs
  529.         do_depth
  530.         PrintF('RELOFS \d',Word(mem+2))
  531.         mem+=4
  532.     ELSEIF mem[0]=8    // offset
  533.         do_depth
  534.         IF Word(mem+2)=4
  535.             PrintF('ALIGN')
  536.         ELSE
  537.             PrintF('ALIGN \d',Word(mem+2))
  538.         ENDIF
  539.         mem+=4
  540.     ELSE
  541.     ENDIF
  542.     SUB do_depth
  543.         DEF    dp=depth
  544.         WHILE dp-- DO PrintF('\t')
  545.     ENDSUB
  546. ENDPROC mem,nmem
  547.  
  548. PROC TypeStr(type)(PTR TO CHAR)
  549.     DEF    str2:PTR TO CHAR,cnt,str:PTR TO CHAR
  550.     str2:='                                                                            '
  551.     str2[0]:="\0"
  552.     cnt:=(type & %11100000)>>5    // obtain the pointer count from the type
  553.     IF cnt>4 THEN cnt--            // here we have to skip the DT_LIST type
  554.  
  555.     SELECT type&%00011111
  556.     CASE 1;    str:='LONG'
  557.     CASE 2;    str:='ULONG'
  558.     CASE 3;    str:='WORD'
  559.     CASE 4;    str:='UWORD'
  560.     CASE 5;    str:='BYTE'
  561.     CASE 6;    str:='UBYTE'
  562.     CASE 7;    str:='FLOAT'
  563.     CASE 8;    str:='DOUBLE'
  564.     CASE 9;    str:='BOOL'
  565.     CASE 10;    str:='\0'
  566.     CASE 11;    str:='PTR'
  567.     CASE 12;    str:='DLONG'
  568.     CASE 13;    str:='UDLONG'
  569.     CASE 14;    str:=IF type&%11100000 THEN 'CHAR' ELSE 'STRING'
  570.     DEFAULT;    str:='VOID'
  571.     ENDSELECT
  572.  
  573.     IF (type&%11100000)=%10000000
  574.         StrCopy(str2,'LIST OF ')
  575.     ELSE
  576.         WHILE cnt
  577.             StrAdd(str2,'PTR TO ')
  578.             cnt--
  579.         ENDWHILE
  580.     ENDIF
  581.     StrAdd(str2,str)
  582. ENDPROC str2
  583.  
  584. MODULE    'exec/memory'
  585.  
  586. ENUM    SOURCE
  587.  
  588. PROC main()
  589.     DEF    rda,args=[0,0]:LONG,l,m:PTR TO CHAR,f
  590.     IF rda:=ReadArgs('SOURCE/A',args,NIL)
  591.         l:=FileLength(args[SOURCE])
  592.         IF f:=Open(args[SOURCE],OLDFILE)
  593.             IF m:=AllocMem(l+8,MEMF_PUBLIC|MEMF_CLEAR)
  594.                 IF Read(f,m,l)=l
  595.                     DisplayMODULE(m)
  596.                 ELSE PrintFault(IOErr(),'dmod')
  597.                 FreeMem(m,l+8)
  598.             ELSE PrintF('\s: not enough memory\n','dmod')
  599.             Close(f)
  600.         ELSE PrintFault(IOErr(),'dmod')
  601.         FreeArgs(rda)
  602.     ELSE PrintFault(IOErr(),'dmod')
  603. ENDPROC
  604.